/**
 * @file    parallel_can.c
 * @brief   并机协议-JBD(CAN)
 * @author  name
 * @version 1.0.1
 * @date    2023-06-12
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-06-12 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "parallel_can.h"
#include "If_can.h"
#include "var_mng.h"
#include "param_mng.h"
#include "cfg_prj.h"
#include "parallel.h"
#include "If_do.h"
#include "If_di.h"
#include "boot_param.h"
#include "FreeRTOS.h"
#include "task.h"
#include "parallel.h"

/* macro/define --------------------------------------------------------------*/
#define FRAME_PRI           (0x18)
#define CAN_CALIB_CMD       (0xF000)
#define CAN_REPLY_CALIB_CMD (0xF001)

#define MASTER_CALC_CYCLE   (3000)
#define SLAVE_TIMEOUT       (3000)
/* typedef -------------------------------------------------------------------*/
typedef struct 
{
    uint16_t can_id;      /* !< 报文ID */
    uint16_t send_cycle; /* !< 发送周期 */
    uint16_t send_cnt;   /* !< 计时器 */
	uint8_t try_times;
    uint8_t (*pfunc_get_frame_msg)(can_frame_type *);
}send_frame_type;

/* local functions -----------------------------------------------------------*/
static uint8_t can_get_0xF100_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF101_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF102_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF103_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF104_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF105_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF106_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF107_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF110_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF180_msg(can_frame_type *can_msg);
static uint8_t can_get_0xF200_msg(can_frame_type *can_msg);
static void can_send_calib_cmd(uint8_t addr , can_frame_type *can_msg);
static void can_reply_calib_cmd(uint8_t addr , can_frame_type *can_msg);
static void parallel_slave_run(uint8_t can_id , uint32_t cycle);
static void parallel_master_run(uint8_t can_id , uint32_t cycle);
static void parallel_recv_slave_data(can_frame_type can_msg);
static void master_normal_run(uint8_t can_id , uint32_t cycle);
static void slave_normal_run(uint8_t can_id , uint32_t cycle);
/* static variables ----------------------------------------------------------*/
static send_frame_type send_frame_list[] = 
{
    {0xF100 , 250 , 0 ,can_get_0xF100_msg },
    {0xF101 , 250 , 0 ,can_get_0xF101_msg },
    {0xF102 , 250 , 0 ,can_get_0xF102_msg },
    {0xF103 , 250 , 0 ,can_get_0xF103_msg },
    {0xF104 , 250 , 0 ,can_get_0xF104_msg },
    {0xF105 , 250 , 0 ,can_get_0xF105_msg },
    {0xF106 , 250 , 0 ,can_get_0xF106_msg },
    {0xF107 , 250 , 0 ,can_get_0xF107_msg },
	{0xF110 , 250 , 0 ,can_get_0xF110_msg } ,
    {0xF180 , 250 , 0 ,can_get_0xF180_msg },
    {0xF200 , 250 , 0 ,can_get_0xF200_msg },
};

#define CAN_LIST_NUM     (sizeof(send_frame_list)/sizeof(send_frame_type))

static auto_addr_state_type auto_calib_state = AUTO_ADDR_START;
static uint8_t calib_slave_addr = 0x02;
static uint16_t check_dly = 0;
static uint16_t slave_chk_dly = 0;
static uint8_t addr_now_state = 0;
static uint16_t can_timeout = 0;
static uint16_t master_update_cnt = 0; 
static uint16_t slave_ol_frame_state[CFG_PARALLEL_NUM] = {0};
static uint8_t run_state = RUN_STATE_AUTO_ADDR;
static uint16_t master_in_on_cnt = 0; // 主机状态下 , IN有效延时计算器,用于判断主机是否转变为从机 */
static uint16_t slave_in_off_cnt = 0;  // 从机状态下 , IN无效延时计算器,用于判断从机是否转变为主机 */
/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
void parallel_can_deal(uint8_t can_id , uint32_t cycle)
{
	if(PAL_MODE_SW_CAN == parallel_get_mode())
	{
		var_set_data(VAR_ID_SELF_ADDR , If_di_read_addr());
		
		if(var_get_data(VAR_ID_SELF_ADDR) == PARALLEL_MASTER_ADDR)
        {
            master_normal_run(can_id , cycle);
        }
        else
        {
            slave_normal_run(can_id , cycle);
        }
	}
	else
	{
		if(addr_now_state == ADDR_STATE_UNDEF)
		{
			check_dly += cycle;
			if(If_di_read_in(DI_ADDR_IN) == DI_IN_ON)
			{
				slave_chk_dly += cycle;
				if(slave_chk_dly >= 1000)
				{
					auto_calib_state = AUTO_ADDR_START;
					run_state = RUN_STATE_NORMAL;
					addr_now_state = ADDR_STATE_CFG;
					var_set_data(VAR_ID_SELF_ADDR , 0x00);
				}
			}
			if(check_dly >= 2000)
			{
				addr_now_state = ADDR_STATE_CFG;
				auto_calib_state = AUTO_ADDR_START;
				run_state = RUN_STATE_AUTO_ADDR;
				var_set_data(VAR_ID_SELF_ADDR , PARALLEL_MASTER_ADDR);
			}
		}
		else
		{
			if(var_get_data(VAR_ID_SELF_ADDR) == PARALLEL_MASTER_ADDR)
			{
				parallel_master_run(can_id , cycle);
			}
			else
			{
				parallel_slave_run(can_id , cycle);
			}
		}
	}
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static void parallel_master_run(uint8_t can_id , uint32_t cycle)
{
    uint8_t i = 0;
    can_frame_type can_send_buf[20] = {0};
    can_frame_type can_recv_buf[20] = {0};
	
	if(RUN_STATE_AUTO_ADDR == run_state)
	{
		switch(auto_calib_state)
		{
			case AUTO_ADDR_START:
				If_do_set_output(DO_AUTO_ADDR , DO_OUT_OFF);
				can_send_calib_cmd(0x00 , can_send_buf);
				If_can_send_frame(can_id , can_send_buf[0]);
				can_timeout += cycle;
				if(can_timeout >= 500)
				{
					can_timeout = 0;
					auto_calib_state = AUTO_ADDR_RUNNING;
					calib_slave_addr = 0x02;
				}
				break;
			case AUTO_ADDR_RUNNING:
				can_timeout += cycle;
				if(can_timeout >= 2000)
				{
					can_send_calib_cmd(0xFF , can_send_buf);
					If_can_send_frame(can_id , can_send_buf[0]);
					vTaskDelay(5);
					If_can_send_frame(can_id , can_send_buf[0]);
					vTaskDelay(5);
					If_can_send_frame(can_id , can_send_buf[0]);
					vTaskDelay(5);
					auto_calib_state = AUTO_ADDR_CMP;
					break;
				}
				else
				{
					for(i = 0;i < 5; ++ i)
					{
						if(If_can_read_one_frame(can_id , can_recv_buf))
						{
							if(((can_recv_buf[0].id >> 8) & 0xffff) ==  CAN_REPLY_CALIB_CMD)
							{
								if((can_recv_buf[0].id & 0xff) == calib_slave_addr)
								{
									calib_slave_addr ++ ;
									can_timeout = 0;
									If_can_clr_buf(can_id);
								}
							}
						}
						else
						{
							break;
						}
					}
					can_send_calib_cmd(calib_slave_addr , can_send_buf);
					If_can_send_frame(can_id , can_send_buf[0]);
				}
				break;
			case AUTO_ADDR_CMP:
				/* 计算一次统计信息 */
				parallel_master_update_self();
				parallel_master_calc();
				auto_calib_state = AUTO_ADDR_CMP;
				run_state = RUN_STATE_NORMAL;  // 标定完成 进入正常状态 
				break;
			default:
				auto_calib_state = AUTO_ADDR_CMP;
				break;
		}
	}
	else  /* 寻址完成进入正常模式 */
	{
		master_normal_run(can_id , cycle);
		
		// 如果检测到IN持续有效 3S , 则进入从机模式
		if(If_di_read_in(DI_ADDR_IN) == DI_IN_ON)
		{
			master_in_on_cnt += cycle;
			if(master_in_on_cnt >= 3000)
			{
				master_in_on_cnt = 0;
				var_set_data(VAR_ID_SELF_ADDR , 0);
			}
		}
		else
		{
			master_in_on_cnt = 0;
		}
	}
}

static void parallel_slave_run(uint8_t can_id , uint32_t cycle)
{
    uint8_t i = 0;
    static uint8_t recv_cnt = 0;
    static uint8_t last_addr = 0;
    can_frame_type can_send_buf[10] = {0};
    can_frame_type can_recv_buf[10] = {0};
    
    if(RUN_STATE_AUTO_ADDR == run_state)
    {
        switch(auto_calib_state)
        {
            case AUTO_ADDR_START:
                if(If_di_read_in(DI_ADDR_IN) == DI_IN_OFF)
                {
                    If_do_set_output(DO_CAN_RES , DO_OUT_ON);
                }
								
                for(i = 0;i < 5; ++ i)
                {
                    if(If_can_read_one_frame(can_id , can_recv_buf))
                    {
                        if(((can_recv_buf->id >> 8) & 0xffff) == CAN_CALIB_CMD)
                        {
                            if(can_recv_buf->data.byte_buf[0] == 0xff)
                            {
                                auto_calib_state = AUTO_ADDR_CMP;
                                If_do_set_output(DO_AUTO_ADDR , DO_OUT_ON);
                            }
                            else if((can_recv_buf->data.byte_buf[0] > 0) && (can_recv_buf->data.byte_buf[0] < 0x20))
                            {
                                if((If_di_read_in(DI_ADDR_IN) == DI_IN_OFF) && (var_get_data(VAR_ID_SELF_ADDR) == 0))
                                {
                                    if(recv_cnt == 0)
                                    {
                                        last_addr = can_recv_buf->data.byte_buf[0];
                                        recv_cnt ++ ;
                                    }
                                    else 
                                    {
                                        if(last_addr == can_recv_buf->data.byte_buf[0])
                                        {
                                            ++ recv_cnt;
                                            if(recv_cnt >= 3)
                                            {
                                                auto_calib_state = AUTO_ADDR_RUNNING;
                                                recv_cnt = 0;
                                                var_set_data(VAR_ID_SELF_ADDR , last_addr);
												param_set_data(PAR_ID_SELF_ADDR , last_addr);
                                            }
                                        } 
                                        else
                                        {
                                            last_addr = can_recv_buf->data.byte_buf[0];
                                            recv_cnt = 1;
                                        }
                                    }
                                }
                            }
						    else
							{
															
							}
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                break;
            case AUTO_ADDR_RUNNING:
                for(i = 0;i < 5; ++ i)
                {
                    if(If_can_read_one_frame(can_id , can_recv_buf))
                    {
                        if(((can_recv_buf->id >> 8) & 0xffff) == CAN_CALIB_CMD)
                        {
                            if(can_recv_buf->data.byte_buf[0] == 0xff)
                            {
                                auto_calib_state = AUTO_ADDR_CMP;
                                If_do_set_output(DO_AUTO_ADDR , DO_OUT_ON);
                            }
                            else if(can_recv_buf->data.byte_buf[0] == (var_get_data(VAR_ID_SELF_ADDR) + 1))
                            {
                                If_do_set_output(DO_CAN_RES , DO_OUT_OFF);
                                If_do_set_output(DO_AUTO_ADDR , DO_OUT_OFF);
                            }
                            else if(can_recv_buf->data.byte_buf[0] == var_get_data(VAR_ID_SELF_ADDR))
                            {
                                can_reply_calib_cmd(var_get_data(VAR_ID_SELF_ADDR) , can_send_buf);
                                If_can_send_frame(can_id , can_send_buf[0]);
                            }
                            else
                            {

                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                break;
            case AUTO_ADDR_CMP:
                run_state = RUN_STATE_AUTO_ADDR;
                break;
            default:
                auto_calib_state = AUTO_ADDR_CMP;
                break;
        }
    }
    else
    {
		slave_normal_run(can_id , cycle);
		
		// 如果检测到IN持续无效 2S , 则进入自动寻址状态
		if(If_di_read_in(DI_ADDR_IN) == DI_IN_OFF)
		{
			slave_in_off_cnt += cycle;
			if(slave_in_off_cnt >= 3000)
			{
				slave_in_off_cnt = 0;
				addr_now_state = ADDR_STATE_UNDEF;
			}
		}
		else
		{
			slave_in_off_cnt = 0;
		}
    }
}

static uint8_t can_get_0xF100_msg(can_frame_type *can_msg)
{
    int32_t bus_curr = 0;
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF100 << 8) | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_BATT_VOLT);

    bus_curr = var_get_data(VAR_ID_BUS_CURR) - 30000; 
    can_msg->data.half_buf[1] = bus_curr >> 16;
    can_msg->data.half_buf[2] = bus_curr & 0xffff;

    can_msg->data.byte_buf[6] = var_get_data(VAR_ID_DISP_SOC) * 0.01;
    can_msg->data.byte_buf[7] = param_get_data(PAR_ID_SOH);

    return 1;
}

static uint8_t can_get_0xF101_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF101 << 8) | var_get_data(VAR_ID_SELF_ADDR);
    
    can_msg->data.byte_buf[0] = param_get_data(PAR_ID_CB_CELL_NUM);
    can_msg->data.byte_buf[1] = sample_calc_temp_num();
    can_msg->data.half_buf[1] = param_get_data(PAR_ID_FULL_CAP);
    can_msg->data.half_buf[2] = param_get_data(PAR_ID_REAL_CAP);
    can_msg->data.half_buf[3] = param_get_data(PAR_ID_CYCLE);

    return 1;
}

static uint8_t can_get_0xF102_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) |  (0xF102 << 8)  | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_AGV_VOLT);
    can_msg->data.half_buf[1] = var_get_data(VAR_ID_AGV_TEMP) + 2231;
    can_msg->data.half_buf[2] = 0;
    can_msg->data.half_buf[3] = 0;

    return 1;
}
static uint8_t can_get_0xF103_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF103 << 8) | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.word_buf[0] = diag_get_all_alarm();
    can_msg->data.word_buf[1] = diag_get_all_prp();

    return 1;
}
static uint8_t can_get_0xF104_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF104 << 8) | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_MAX_CELL_VOLT);
    can_msg->data.half_buf[1] = var_get_data(VAR_ID_MIN_CELL_VOLT);
    can_msg->data.half_buf[2] = var_get_data(VAR_ID_MAX_TEMP_VAL) + 2231;
    can_msg->data.half_buf[3] = var_get_data(VAR_ID_MIN_TEMP_VAL) + 2231;
    return 1;
}

static uint8_t can_get_0xF105_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF105 << 8) | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.byte_buf[0] = var_get_data(VAR_ID_HARD_VER);
    can_msg->data.byte_buf[1] = boot_param_read_par(BP_ID_BOOT_VER);
    can_msg->data.byte_buf[2] = SOFT_VER_MAIN;
    can_msg->data.byte_buf[3] = SOFT_VER_RELEASE;
    can_msg->data.byte_buf[4] = SOFT_VER_TEST;

    return 1;
}

static uint8_t can_get_0xF106_msg(can_frame_type *can_msg)
{
    uint8_t i = 0;

    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF106 << 8) | var_get_data(VAR_ID_SELF_ADDR);

    for(i = 0;i < 4; ++ i)
    {
        can_msg->data.half_buf[i] = param_get_data(PAR_ID_SN_CODE + i);
    }

    return 1;
}

static uint8_t can_get_0xF107_msg(can_frame_type *can_msg)
{
    uint8_t i = 0;

    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF107 << 8) | var_get_data(VAR_ID_SELF_ADDR);

    for(i = 0;i < 4; ++ i)
    {
        can_msg->data.half_buf[i] = param_get_data(PAR_ID_SN_CODE + 4 + i);
    }

    return 1;
}

static uint8_t can_get_0xF110_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (0xF110 << 8) | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_SOP_CC);
	can_msg->data.half_buf[0] = var_get_data(VAR_ID_SOP_DC);
	can_msg->data.half_buf[0] = var_get_data(VAR_ID_SOP_CV);
	can_msg->data.half_buf[0] = var_get_data(VAR_ID_SOP_DV);

    return 1;
}

static uint8_t can_get_0xF180_msg(can_frame_type *can_msg)
{
    uint8_t send_num = 0;
    uint8_t i = 0;
    uint8_t j = 0;
    can_frame_type *p_can_msg = can_msg;

    for( i = 0;i < CFG_CELL_NUM; ++ i)
    {
        p_can_msg->data.half_buf[j ++ ] = var_get_data(VAR_ID_CELL_VOLT01 + i);
        if(j >= 4)
        {
            j = 0;
            p_can_msg->frame_type = CAN_FRAME_DATA;
            p_can_msg->id_type = CAN_ID_EXT;
            p_can_msg->dlc = 8;
            p_can_msg->id = (FRAME_PRI << 24) | ((0xF180 + i / 4) << 8) | var_get_data(VAR_ID_SELF_ADDR);
            ++ p_can_msg;
            ++ send_num;
        } 
    }
    return send_num;
}

static uint8_t can_get_0xF200_msg(can_frame_type *can_msg)
{
    uint8_t send_num = 0;
    uint8_t i = 0;
    uint8_t j = 0;
    can_frame_type *p_can_msg = can_msg;

    for( i = 0;i < CFG_TEMP_NUM; ++ i)
    {
        p_can_msg->data.half_buf[j ++ ] = var_get_data(VAR_ID_CELL_TEMP01 + i) + 2231;
        if(j >= 4)
        {
            j = 0;
            p_can_msg->frame_type = CAN_FRAME_DATA;
            p_can_msg->id_type = CAN_ID_EXT;
            p_can_msg->dlc = 8;
            p_can_msg->id = (FRAME_PRI << 24) | ((0xF200 + i / 4) << 8) | var_get_data(VAR_ID_SELF_ADDR);
            ++ p_can_msg;
            ++ send_num;
        } 
    }
    return send_num;
}

static void can_send_calib_cmd(uint8_t addr , can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (CAN_CALIB_CMD << 8) | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.byte_buf[0] = addr;
    can_msg->data.byte_buf[1] = 0x01;
}

static void can_reply_calib_cmd(uint8_t addr , can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = (FRAME_PRI << 24) | (CAN_REPLY_CALIB_CMD << 8) | var_get_data(VAR_ID_SELF_ADDR);

    can_msg->data.byte_buf[0] = addr;
    can_msg->data.byte_buf[1] = 0x02;
}

static void parallel_recv_slave_data(can_frame_type can_msg)
{
    uint8_t slave_addr = 0;
    uint16_t pdu_id = 0;
    uint8_t i = 0;
    uint8_t base_addr = 0;

    slave_addr = can_msg.id & 0xff;

    if(slave_addr == 0)
    {
        //TODO 存在位标定的模块存在
        return ;
    }

    if(slave_addr >= CFG_PARALLEL_NUM)
        return ;
    
    slave_addr -= 1;
    pdu_id = (can_msg.id >> 8) & 0xffff;

    /* 基本信息 */
    if(0xF100 == pdu_id)
    {
        master_data_reg.slave_data[slave_addr].batt_volt = can_msg.data.half_buf[0];
        master_data_reg.slave_data[slave_addr].curr_h16 = can_msg.data.half_buf[1];
        master_data_reg.slave_data[slave_addr].curr_l16 = can_msg.data.half_buf[2];
        master_data_reg.slave_data[slave_addr].soc = can_msg.data.byte_buf[6];
        master_data_reg.slave_data[slave_addr].soh = can_msg.data.byte_buf[7];

        slave_ol_frame_state[slave_addr] |= (1 << 0);
    }
    else if(0xF101 == pdu_id)
    {
        master_data_reg.slave_data[slave_addr].cell_num = can_msg.data.byte_buf[0];
       // master_data_reg.slave_data[slave_addr].temp_num = can_msg.data.byte_buf[1];
        master_data_reg.slave_data[slave_addr].full_cap = can_msg.data.half_buf[1];
        master_data_reg.slave_data[slave_addr].real_cap = can_msg.data.byte_buf[2];
        master_data_reg.slave_data[slave_addr].cycle = can_msg.data.byte_buf[3];

        slave_ol_frame_state[slave_addr] |= (1 << 1);
    }
    else if(0xF102 == pdu_id)
    {
        //master_data_reg.slave_data[slave_addr]. = can_msg.data.byte_buf[0];
        //master_data_reg.slave_data[slave_addr].temp_num = can_msg.data.half_buf[1];
        //master_data_reg.slave_data[slave_addr].full_cap = can_msg.data.half_buf[2];
        master_data_reg.slave_data[slave_addr].fet_status = can_msg.data.byte_buf[2];
        //master_data_reg.slave_data[slave_addr].cycle = can_msg.data.byte_buf[3];
        slave_ol_frame_state[slave_addr] |= (1 << 2);
    }
    else if(0xF103 == pdu_id)
    {
        // 故障信息 
        slave_ol_frame_state[slave_addr] |= (1 << 3);
    }
    else if(0xF104 == pdu_id)
    {
        master_data_reg.slave_data[slave_addr].max_cell_volt = can_msg.data.half_buf[0]; 
        master_data_reg.slave_data[slave_addr].min_cell_volt = can_msg.data.half_buf[1];
        master_data_reg.slave_data[slave_addr].max_temp = can_msg.data.half_buf[2];
        master_data_reg.slave_data[slave_addr].min_temp = can_msg.data.half_buf[3];

        slave_ol_frame_state[slave_addr] |= (1 << 4);
    }
    else if(0xF105 == pdu_id)
    {
        master_data_reg.slave_data[slave_addr].version = can_msg.data.byte_buf[3]; 
        slave_ol_frame_state[slave_addr] |= (1 << 5);
    }
    else if(0xF106 == pdu_id)
    {
        for(i = 0; i < 8; ++ i)
        {
            master_data_reg.slave_data[slave_addr].sn_code[i] = can_msg.data.byte_buf[i];
        }
        slave_ol_frame_state[slave_addr] |= (1 << 6);
    }
    else if(0xF107 == pdu_id)
    {
        for(i = 0; i < 8; ++ i)
        {
            if(i + 8 < 13)
                master_data_reg.slave_data[slave_addr].sn_code[i + 8] = can_msg.data.byte_buf[i];
            else
                break;
        }
        slave_ol_frame_state[slave_addr] |= (1 << 7);
    }
	else if(0xF110 == pdu_id)
    {
        master_data_reg.slave_data[slave_addr].sop_cc = can_msg.data.half_buf[0]; 
        master_data_reg.slave_data[slave_addr].sop_dc = can_msg.data.half_buf[1];
        slave_ol_frame_state[slave_addr] |= (1 << 8);
    }
    else if((pdu_id >= 0xF180) && (pdu_id <= 0xF1FF))
    {
        base_addr = (pdu_id - 0xF180) * 4;
        for(i = 0; i < 4; ++ i)
        {
            if( i + base_addr < CFG_PARALLEL_NUM)
                master_data_reg.slave_data[slave_addr].cell_volt_buf[i + base_addr] = can_msg.data.byte_buf[i];
            else
                break;
        }

        //slave_ol_frame_state[slave_addr] |= (1 << (8 + ());
    }
    else if((pdu_id >= 0xF200) && (pdu_id <= 0xF220))
    {
        
    }
    else
    {
        
    }
}

static void master_normal_run(uint8_t can_id , uint32_t cycle)
{
    uint8_t i = 0;
    can_frame_type can_recv_buf[20] = {0};
    static uint16_t can_slave_state = 0;
	
	for( i = 0; i < 10; ++ i)
	{
		if(If_can_read_one_frame(can_id , can_recv_buf))
		{
			if(((can_recv_buf[0].id >> 24) & FRAME_PRI) == FRAME_PRI)
			{
				parallel_recv_slave_data(can_recv_buf[0]);
			}
		}
		else
		{
			break;
		}
	}
	/* 更新主机统计信息 */
	master_update_cnt += cycle;
	if(master_update_cnt >= MASTER_CALC_CYCLE)
	{
		master_update_cnt = 0;
		can_slave_state |= 0x0001;
		parallel_master_update_self();
		/** 检测从机是否在线 */
		for(i = 1;i < CFG_PARALLEL_NUM; ++ i)
		{
			if((slave_ol_frame_state[i] & 0xFF) == 0xFF)
			{
				can_slave_state |= (1 << i);
			}
            else
			{
				can_slave_state &= ~(1 << i);
				parallel_clear_slave(i); 
			}
			slave_ol_frame_state[i] = 0; // 清除标记值
		}
		var_set_data(VAR_ID_TP_PACK_OL_ST , can_slave_state);
		parallel_master_calc();
	}	
}

static void slave_normal_run(uint8_t can_id , uint32_t cycle)
{
	uint8_t i = 0;
    uint8_t j = 0;
    uint8_t msg_num = 0;
	uint32_t recv_id = 0;
    can_frame_type can_send_buf[20] = {0};
    can_frame_type can_recv_buf[20] = {0};
	
	for( i = 0; i < CAN_LIST_NUM; ++ i)
	{
		send_frame_list[i].send_cnt += cycle;
		if(send_frame_list[i].send_cnt >= send_frame_list[i].send_cycle)
		{
			send_frame_list[i].send_cnt = 0;
			msg_num = send_frame_list[i].pfunc_get_frame_msg(can_send_buf); 
			for( j = 0;j < msg_num; ++ j)
			{
				If_can_send_frame(can_id , can_send_buf[j]);
			}
		}
	}

	for(i = 0;i < 5; ++ i)
	{
		if(If_can_read_one_frame(can_id , can_recv_buf))
		{
			recv_id = (FRAME_PRI << 24) | (CAN_CALIB_CMD << 8) | PARALLEL_MASTER_ADDR;
			if((recv_id == can_recv_buf[0].id) && (can_recv_buf[0].data.byte_buf[0] == 0x00))
			{
				var_set_data(VAR_ID_SELF_ADDR , 0);
				auto_calib_state = AUTO_ADDR_START;
				run_state = RUN_STATE_AUTO_ADDR;
				If_can_clr_buf(can_id);
				break;
			}
		}
        else
		{
            break;
		}
	}
}
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
